/**
 * 正则表达式、校验封装：
 *
 * 用法：
 *  1.表达式：Pattern.integerRegex;
 *  2.校验：
 *    Rules.integer(required, msg, trigger, min, max, extend);
 *    Rules.telephone(required, msg, trigger, extend);
 *    ......
 *
 *    参数说明：
 *      required：是否必填。
 *      msg：必填提示。
 *      trigger：触发方式change、blur，默认blur。
 *      min：范围校验最小值。
 *      max：范围校验最大值。
 *      extend：扩展，数组对象。如：[{ required: true, message: "xxx不能为空", trigger: "blur" }]。
 *
 */
// 整数
const integerRegex = /(^-?[1-9]\d*)|(0{1})$/;

// 正整数
const integerPlusRegex = /^[+]{0,1}(\d+)$/;

// 小数
const decimalRegex = /^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$/;

// 正小数
const decimalPlusRegex = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/;

// 百分比校验（最多两位小数,不能超过100，不带百分号）
const percentageRegex = /^(((\d|[1-9]\d)(\.\d{1,2})?)|100|100.0|100.00)$/;

// 邮箱
const emailRegex = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;

// 手机
const mobileRegex = /^0{0,1}(13[0-9]|14[01456789]|15[012356789]|16[2567]|17[012345678]|18[0-9]|19[012356789])[0-9]{8}$/;

// 电话号码
const telephoneRegex = /^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$/;

// 金额校验（不能超过两位小数）
const moneyRegex = /^(([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/;

// 金额校验，支持负数
const moneyNegativeRegex = /^((-?[1-9]{1}\d*)|(-?0{1}))(\.\d{1,2})?$/;

// 银行帐号或卡号
const bankAccountRegex = /^([1-9]{1})(\d{14}|\d{18})$/;

// 居住地
const residenceRegex = /^.+市.+(县|区).+(镇|村|乡|街|路).+(号|室|户).*$/;

// 户口地址
const hkadrRegex = /^.+省.+市.+(县|区).+(镇|村|乡|街|路).+(号|室|户).*$/;

// 密码
const passwordRegex = /([a-zA-z]+\d+\S*\W+\S*)|(\d+[a-zA-z]+\S*\W+\S*)|(\d+\W+\S*[a-zA-z]+\S*)|([a-zA-z]+\W+\S*\d+\S*)|(\W+[a-zA-z]+\S*\d+\S*)|(\W+\d+\S*[a-zA-z]+\S*)/;

function getRegex(regex, msg, trigger, extend) {
  const list = getDefaultRegex(regex, msg, trigger);
  appendExtend(list, extend);
  return list;
}

function getRangeRegex(min, max, regex, msg, trigger, extend) {
  const list = getDefaultRegex(regex, msg, trigger, extend);
  appendRange(list, min, max);
  appendExtend(list, extend);
  return list;
}

function checkNull(val) {
  return val != undefined && val != null;
}

function appendExtend(list, extend) {
  if (Array.isArray(extend) && extend.length > 0) {
    extend.forEach((e) => {
      list.push(e);
    });
  }
}

function appendRange(list, min, max) {
  if (checkNull(min) || checkNull(max)) {
    list.push({
      validator: (rules, value, callback) => {
        if (checkNull(max) && value > max) {
          return callback(new Error("超出范围"));
        } else if (checkNull(min) && value < min) {
          return callback(new Error("超出范围"));
        } else {
          return callback();
        }
      },
      trigger: trigger,
    });
  }
}

function getDefaultRegex(regex, msg, trigger = "blur") {
  return [
    {
      pattern: regex,
      message: msg,
      trigger: trigger,
    },
  ];
}
function addQuired(list, required, msg, trigger = "blur") {
  if (typeof required == Boolean || required) {
    msg = msg == undefined ? "" : msg;
    const obj = { required: true, message: msg, trigger: trigger };
    list.unshift(obj);
  }
}

function integer(required, msg, trigger, min, max, extend) {
  const list = getRangeRegex(
    min,
    max,
    integerRegex,
    "请输入整数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function integerPlus(required, msg, trigger, min, max, extend) {
  const list = getRangeRegex(
    min,
    max,
    integerPlusRegex,
    "请输入正整数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function decimal(required, msg, trigger, min, max, extend) {
  const list = getRangeRegex(
    min,
    max,
    decimalRegex,
    "请输入小数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function decimalPlus(required, msg, trigger, min, max, extend) {
  const list = getRangeRegex(
    min,
    max,
    decimalPlusRegex,
    "请输入正小数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function percentage(required, msg, trigger, extend) {
  const list = getRegex(
    percentageRegex,
    "请输入正确的百分数，最多两位小数,不能超过100",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function email(required, msg, trigger, extend) {
  const list = getRegex(emailRegex, "请输入正确的邮箱", trigger, extend);
  addQuired(list, required, msg, trigger);
  return list;
}

function mobile(required, msg, trigger, extend) {
  const list = getRegex(mobileRegex, "请输入正确的手机号", trigger, extend);
  addQuired(list, required, msg, trigger);
  return list;
}

function telephone(required, msg, trigger, extend) {
  const list = getRegex(
    telephoneRegex,
    "请输入正确的电话号码",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function money(required, msg, trigger, extend) {
  const list = getRegex(
    moneyRegex,
    "请输入正确的金额，不能超过两位小数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function moneyNegative(required, msg, trigger, extend) {
  const list = getRegex(
    moneyNegativeRegex,
    "请输入正确的金额，不能超过两位小数",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function bankAccount(required, msg, trigger, extend) {
  const list = getRegex(
    bankAccountRegex,
    "银行帐号或卡号格式不对",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function residence(required, msg, trigger, extend) {
  const list = getRegex(
    residenceRegex,
    "地址格式不对，请按格式输入：-市-县/区-镇/村/乡/街/路-号/室/户",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function hkadr(required, msg, trigger, extend) {
  const list = getRegex(
    hkadrRegex,
    "地址格式不对，请按格式输入：-省-市-县/区-镇/村/乡/街/路-号/室/户",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

function password(required, msg, trigger, extend) {
  const list = getRegex(
    passwordRegex,
    "密码必须同时由字母、数字、特殊符号(不包括_)等8位以上字符组成",
    trigger,
    extend
  );
  addQuired(list, required, msg, trigger);
  return list;
}

export default {
  Pattern: {
    integerRegex,
    integerPlusRegex,
    decimalRegex,
    decimalPlusRegex,
    percentageRegex,
    emailRegex,
    mobileRegex,
    telephoneRegex,
    moneyRegex,
    moneyNegativeRegex,
    bankAccountRegex,
    residenceRegex,
    hkadrRegex,
    passwordRegex
  },

  Rules: {
    integer: function (required, msg, trigger, min, max, extend) {
      return integer(required, msg, trigger, min, max, extend);
    },
    integerPlus: function (required, msg, trigger, min, max, extend) {
      return integerPlus(required, msg, trigger, min, max, extend);
    },
    decimal: function (required, msg, min, max, extend) {
      return decimal(required, msg, min, max, extend);
    },
    decimalPlus: function (required, msg, min, max, extend) {
      return decimalPlus(required, msg, min, max, extend);
    },
    percentage: function (required, msg, extend) {
      return percentage(required, msg, extend);
    },
    email: function (required, msg, extend) {
      return email(required, msg, extend);
    },
    mobile: function (required, msg, extend) {
      return mobile(required, msg, extend);
    },
    telephone: function (required, msg, extend) {
      return telephone(required, msg, extend);
    },
    money: function (required, msg, extend) {
      return money(required, msg, extend);
    },
    moneyNegative: function (required, msg, extend) {
      return moneyNegative(required, msg, extend);
    },
    bankAccount: function (required, msg, trigger, extend) {
      return bankAccount(required, msg, trigger, extend);
    },
    residence: function (required, msg, trigger, extend) {
      return residence(required, msg, trigger, extend);
    },
    hkadr: function (required, msg, trigger, extend) {
      return hkadr(required, msg, trigger, extend);
    },
    password: function (required, msg, trigger, extend) {
      return password(required, msg, trigger, extend);
    }
  },
};
